package lk.icta.common.service.impl;

import lk.icta.common.AppConstants;
import lk.icta.common.entity.DSDivision;
import lk.icta.common.service.SmsSenderService;
import lk.icta.core.entity.Holder;
import lk.icta.sms.*;
import lk.icta.user.entity.User;
import lk.icta.user.service.UserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;


public class SmsSenderServiceImpl implements SmsSenderService {
    private static final Logger logger = LoggerFactory.getLogger(SmsSenderServiceImpl.class);
    private final ObjectFactory smsFactory;
    private final UserManager userManager;


    public SmsSenderServiceImpl(UserManager userManager) {
        this.userManager = userManager;
        this.smsFactory = new ObjectFactory();
    }

    public boolean sendSMS(String text, String recepient) {
        boolean success = true;
        try {
            SMSAck ack = smsFactory.createSMSAck();
            SMSRequestData smsData = smsFactory.createSMSRequestData();
            smsData.setDepCode(AppConstants.GOVSMS_DEP_CODE);
            smsData.setOutSms(text);
            smsData.setRecepient(recepient);
            smsData.setBillable(smsFactory.createSMSRequestDataBillable(""));
            smsData.setSmscId(smsFactory.createSMSRequestDataSmscId(""));

            SMSRequest smsRequest = smsFactory.createSMSRequest();

            smsRequest.getRequestData().add(smsData);
            MTSmsHandlerService service = new MTSmsHandlerService();

            service.setHandlerResolver(new HandlerResolver() {
                public List<Handler> getHandlerChain(PortInfo portInfo) {
                    List<Handler> handlerList = new ArrayList<Handler>();
                    handlerList.add(new SMSSOAPHandler());
                    return handlerList;
                }
            });

            ack = service.getSmsHandlerServiceHttpSoap11Endpoint().sendSms(smsRequest);

            logger.info("SMS Delivery Status: {}", ack.getAckMessage());
        } catch (GovSMSAuthenticationFault govSMSAuthenticationFault) {
            success = false;
            govSMSAuthenticationFault.printStackTrace();
        } catch (GovSMSInvalidDepartmentFault govSMSInvalidDepartmentFault) {
            success = false;
            govSMSInvalidDepartmentFault.printStackTrace();
        } catch (GovSMSRoutingFault govSMSRoutingFault) {
            success = false;
            govSMSRoutingFault.printStackTrace();
        } catch (Exception e) {
            success = false;
            e.printStackTrace();
        }

        return success;
    }

    public void notifyBySms(Set<DSDivision> dsDivs, User user, String status) {
        logger.debug("------------------------------------->> Status : {}", status);
        for (DSDivision dsDiv : dsDivs) {
            List<User> users = userManager.getUsersByRoleDS("LO", dsDiv.getId(), user);
            /*if(!(users.size()>0)){
                continue;
            }*/
            String message = "The land application " + status + " by " + user.getRole().getName(); // the message might have to be changed
            for (User u : users) {
                String mobile = u.getMobile();
                if (mobile != null) {
                    boolean success = sendSMS(message, mobile);
                    if (success) {
                        logger.debug("------------------------------------->>SMS sent to User : {} SMS :{}", u.getFullName(), mobile);
                    } else {
                        logger.debug("SMS sending to all in DS division failed with exception");
                    }
                }
            }
        }
    }


    public boolean sendSmsToSlcUser(User slcUser, String message) {
        //logger.debug("------------------------------------->> Status : {}", username);
        boolean success = false;

        String mobile = slcUser.getMobile();
        if (mobile != null) {
            success = sendSMS(message, mobile);
            if (success) {
                logger.debug("--------->>SMS sent to User : {} SMS :{}", slcUser.getFullName(), mobile);
            } else {
                logger.debug("SMS sending to SLC user : {} and no: {} failed due to service exception", slcUser.getFullName(), mobile);
            }
        }
        return success;
    }

    public void sendSmsToHolder(Holder holder, String message) {
        //logger.debug("------------------------------------->>SMS sent to Holder : {}", holder.getName());
        boolean success = false;
        String mobile = holder.getContacts().getMobile();
        if (mobile != null) {
            success = sendSMS(message, mobile);
            if (success) {
                logger.debug("------------------------------------->>SMS sent to Holder : {} SMS :{}", holder.getName(), mobile);
            } else {
                logger.debug("SMS sending to Holder failed with exception");
            }
        }
    }
}
